前幾天都在趕進度,今天稍稍放慢腳步補充之前在 Day11 提到的依賴注入(Dependency Injection)。這個設計模式在大型專案中尤為重要,我們可以利用它來降低耦合度、提高可測試性,並且更靈活地管理物件之間的依賴關係。
依賴注入的核心概念很簡單,就是將一個物件的依賴交由外部來管理,而不是在物件內部自行建立或初始化。這樣做的好處是,我們可以靈活替換依賴物件,進而提高模組化和測試性。
舉個簡單例子,我們先來看一個沒有使用依賴注入的程式碼範例:
class UserManager {
private let networkService = NetworkService()
func fetchUserData() {
networkService.requestData()
}
}
這裡 UserManager 直接依賴於 NetworkService
,這會導致無法輕鬆替換 NetworkService
(例如在測試環境中),並且兩個類之間的耦合度過高。
我們可以透過依賴注入來改進這個結構,讓 UserManager 接收 NetworkService
作為外部傳入的依賴:
class UserManager {
private let networkService: NetworkService
init(networkService: NetworkService) {
self.networkService = networkService
}
func fetchUserData() {
networkService.requestData()
}
}
這樣 UserManager 就不再自行管理 NetworkService
的實例,而是依賴於外部注入的 NetworkService
,使得我們可以輕鬆地替換為不同的實作,例如在測試時使用 mock 物件。
在 SwiftUI 中,我們可以透過 @EnvironmentObject
或 @StateObject
等方式來進行依賴注入。例如,我們可以將 DataManager 作為依賴注入到多個 View 中。
首先,我們來定義一個簡單的 DataManager 類,用來管理資料操作。
class DataManager: ObservableObject {
@Published var items: [Item] = []
func fetchItems() {
// 模擬資料抓取
self.items = [
Item(name: "蘋果", quantity: 2, price: 30),
Item(name: "橘子", quantity: 3, price: 50)
]
}
func addItem(_ item: Item) {
items.append(item)
}
}
這個 DataManager 是一個 ObservableObject
,我們可以將它注入到 View
中,讓不同的 View 共享資料。
在 SwiftUI 中,我們可以在 App 或 Scene 中使用 @StateObject
來建立 DataManager,然後將它注入到子 View 中。
@main
struct MyApp: App {
@StateObject private var dataManager = DataManager()
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(dataManager) // 注入 DataManager 到環境中
}
}
}
這樣,DataManager 就會被注入到 ContentView 以及所有子 View 的環境中,我們可以在任意一個 View 中取得 DataManager。
接著,我們在 ContentView 中注入 DataManager,並展示資料。
struct ContentView: View {
@EnvironmentObject var dataManager: DataManager // 注入 DataManager
var body: some View {
NavigationView {
List {
ForEach(dataManager.items) { item in
Text("\(item.name): \(item.quantity) 個 - \(item.price) 元")
}
}
.navigationTitle("家用品清單")
.onAppear {
dataManager.fetchItems() // 當 View 顯示時抓取資料
}
}
}
}
在這裡,@EnvironmentObject
自動從上層環境中取得 DataManager,這樣 ContentView 就不需要自行管理資料的來源,依賴關係也變得更加靈活。
今天我們認識依賴注入的概念,並在 SwiftUI 中實作了這個設計模式。透過依賴注入,我們可以減少物件之間的耦合,提升系統的可維護性與測試性。特別是在大型專案中,依賴注入可以有效地幫助我們管理物件間的依賴,讓系統更加靈活。明天我們將繼續優化我們的專案,敬請期待!
參考資料: